package hanoi.tower;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.GregorianCalendar;
import java.util.List;
import java.util.Stack;
import java.util.Vector;

import search.algorithms.*;
import es.deusto.ingenieria.is.Hanoi.formulation.Ficha;
import es.deusto.ingenieria.is.Hanoi.formulation.TorreHanoiState;
import es.deusto.ingenieria.is.Hanoi.formulation.Mover_Ficha;
import es.deusto.ingenieria.is.Hanoi.formulation.Torre;
import es.deusto.ingenieria.is.search.formulation.Problem;

public class TorreHanoiProblem extends Problem {
	
	private int nFichass;
	private int nTorres;
	private int toreInicial;
	private int torreFinal;
	
	public Problema_Hanoi(int nFichas, int ntorre, int torreInicial,
			int torreFinal) {
		super();
		this.nFichas = nFichas;
		this.nTorress = nTorress;
		this.torreInicial = torreInicial;
		this.torreFinal = torreFinal;
		this.createInitialState();
		this.createFinalState();
		this.createOperators();
	}
	
//revisar
	public void createInitialState () {
		List<Torre> a=new List<Torre>(nTorres);
		for(int i=0;i<nTorres;i++){
			if(i+1==this.TorreInicial){
			Stack<Ficha> s=new Stack<Ficha>();
			for(int j=0;j<this.nFichas;j++){
				Ficha f=new Ficha(nFichas-j);
				s.push(f);
			}
			a.add(i,new Torre(i+1, this.nFichas, s));
			}else{
				a.add(i,new Torre(i+1, 0, new Stack<Ficha>()));
			}
		}
		this.addInitialState(new TorreHanoiState(a, this.getTorreInicial(),this.getTorreFinal(),this.getnFichas()));
		
	}
	
	public void createFinalState(){
		List<Torre> a=new List<Torre>(nTorres);
		for(int i=0;i<nTorres;i++){
			if(i+1==this.TorreFinal){
			Stack<Ficha> s=new Stack<Ficha>();
			for(int j=0;j<this.nFichas;j++){
				Ficha d=new Ficha(nFichas-j);
				s.push(d);
			}
			a.add(i,new Torre(i+1, this.nFichas, s));
			}else{
				a.add(i,new Torre(i+1, 0, new Stack<Ficha>()));
			}
		}
		this.addFinalState(new TorreHanoiState(a, this.getTorreInicial(),this.getTorreFinal(),this.getnFichas()));
	}
	//revisar
	
	public void createOperators() {
		TorreHanoiState eInicial=(TorreHanoiState)this.getInitialStates().get(0);
		for(int i=0;i<nTorres;i++){
			for(int j=0;j<nTorres;j++){
				if(j!=i){
					this.addOperator(new Mover_Ficha(eInicial.getTorres().get(i),eInicial.getTorres().get(j)));
				}
			}
		}
	}	
	
	public static boolean isFinalState(TorreHanoiState state){
		List vTorres=state.getvTorres();
		Torre tDest=(Torre) vTorres.get(state.getTorreObjetivo());
		boolean esFinal=true;
		if(tDest.ns==state.getNums()){
			
		for(int i=1; i<state.getNums();i++){
			 f1=() tDest.getTorres().elementAt(i-1);
			 f2=() tDest.getTorres().elementAt(i);
			if(f1.tamano<f2.tamano){
				esFinal=false;
			}
			
		}
		
	   }else esFinal=false;
		return esFinal;
	}
	
	
public void solve(SearchMethod searchMethod){
	SimpleDateFormat formatter = new SimpleDateFormat("hh:mm:ss.SSS");
	System.out.println("* Start '" + searchMethod.getClass().getSimpleName() + "' (" + formatter.format(GregorianCalendar.getInstance().getTime()) + ")");
	Node finalNode = searchMethod.search(this, this.getInitialStates().get(0));
	System.out.println("* End   '" + searchMethod.getClass().getSimpleName() + "' (" + formatter.format(GregorianCalendar.getInstance().getTime()) + ")");		
	
	if (finalNode != null) {
		System.out.println("\n- :-) Solution found!");
		List<String> operators = new ArrayList<String>();
		searchMethod.solutionPath(finalNode, operators);
		searchMethod.createSolutionLog(operators);
	} else {
		System.out.println("\n- :-( Unable to find the solution!");
	}
}

	


public static void main (String [] args) {
	
	 f1= new ();
	f1.setTamano(2);
	f1.setOrden(0);
	
	 f2= new ();
	f2.setTamano(4);
	f2.setOrden(1);
	
	 f3= new ();
	f3.setTamano(6);
	f3.setOrden(2);
	
	Torre t1= new Torre();
	t1.setPosicion(0);
	t1.setNs(0);
	
	Torre t2= new Torre();
	t2.setPosicion(1);
	t2.setNs(0);
	
	Torre t3= new Torre();
	t3.setPosicion(2);
	t3.setNs(3);
	Stack vs= new Stack(); 
	Vector vTorres= new Vector<>(3);
	vs.addElement(f3);
	vs.addElement(f2);
	vs.addElement(f1);
	t3.torre=vs;
	vTorres.addElement(t1);
	vTorres.addElement(t2);
	vTorres.addElement(t3);
	
	
	TorreHanoiState s1= new TorreHanoiState(vTorres,3,3,t3.getPosicion(), 0);
	
	
	//System.out.println(isFinalState(s1));
	//Mover m1= new Mover(t3,t2);
	//System.out.println(m1.IsApplicable());
	//m1.Effect();
	
	
    }
	
	
}
